package cn.exrick.xboot.modules.activiti.controller;

import cn.exrick.xboot.common.constant.ActivitiConstant;
import cn.exrick.xboot.common.exception.XbootException;
import cn.exrick.xboot.common.utils.ResultUtil;
import cn.exrick.xboot.common.utils.SecurityUtil;
import cn.exrick.xboot.common.vo.PageVo;
import cn.exrick.xboot.common.vo.Result;
import cn.exrick.xboot.common.vo.SearchVo;
import cn.exrick.xboot.config.properties.ActivitiExtendProperties;
import cn.exrick.xboot.modules.activiti.entity.ActBusiness;
import cn.exrick.xboot.modules.activiti.vo.ActProcessInstance;
import cn.exrick.xboot.modules.activiti.entity.ActProcess;
import cn.exrick.xboot.modules.activiti.entity.business.EventReport;
import cn.exrick.xboot.modules.activiti.service.ActBusinessService;
import cn.exrick.xboot.modules.activiti.service.ProcessInstanceService;
import cn.exrick.xboot.modules.activiti.service.ActProcessService;
import cn.exrick.xboot.modules.activiti.service.business.EventReportService;
import cn.exrick.xboot.modules.activiti.vo.*;
import cn.exrick.xboot.modules.base.entity.User;
import cn.exrick.xboot.modules.base.service.DepartmentService;
import cn.exrick.xboot.modules.base.service.UserService;
import cn.hutool.core.date.DateUtil;
import cn.hutool.core.util.StrUtil;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import io.swagger.annotations.ApiParam;
import lombok.extern.slf4j.Slf4j;
import org.activiti.bpmn.model.*;
import org.activiti.engine.*;
import org.activiti.engine.history.HistoricIdentityLink;
import org.activiti.engine.history.HistoricProcessInstance;
import org.activiti.engine.history.HistoricProcessInstanceQuery;
import org.activiti.engine.history.HistoricTaskInstance;
import org.activiti.engine.repository.ProcessDefinition;
import org.activiti.engine.runtime.ProcessInstance;
import org.activiti.engine.task.Task;
import org.activiti.image.ProcessDiagramGenerator;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.bind.annotation.*;

import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.io.InputStream;
import java.net.URLEncoder;
import java.util.*;

/**
 * @author Exrick
 */
@Slf4j
@RestController
@Api(description = "流程实例管理接口")
@RequestMapping("/xboot/actProcess")
@Transactional
public class ActProcessInsController {

    @Autowired
    private EventReportService eventReportService;

    @Autowired
    private ActivitiExtendProperties properties;

    @Autowired
    private SecurityUtil securityUtil;

    @Autowired
    private ActProcessService actProcessService;

    @Autowired
    private RepositoryService repositoryService;

    @Autowired
    private RuntimeService runtimeService;

    @Autowired
    private HistoryService historyService;

    @Autowired
    private TaskService taskService;

    @Autowired
    private ActBusinessService actBusinessService;

    @Autowired
    private UserService userService;

    @Autowired
    private ProcessEngineConfiguration processEngineConfiguration;

    @Autowired
    private DepartmentService departmentService;

    @Autowired
    private ProcessInstanceService processInstanceService;

    @RequestMapping(value = "/getRunningProcess", method = RequestMethod.GET)
    @ApiOperation(value = "获取运行中的流程实例")
    public Result<Object> getRunningProcess(@RequestParam(required = false) String name,
                                            @RequestParam(required = false) String depId,
                                            @RequestParam(required = false) String categoryId,
                                            @RequestParam(required = false) String key,
                                            @RequestParam(required = false) String locality,
                                            @RequestParam(required = false) String eventDescribe,
                                            @RequestParam(required = false) String eventType,
                                            @RequestParam(required = false) String eventNum,
                                            @RequestParam(required = false) String depPineId,
                                            @RequestParam(required = false) String stage,
                                            @ModelAttribute SearchVo searchVo,
                                            @ModelAttribute PageVo pageVo){



        ActPage<ProcessInsVo> page = new ActPage<ProcessInsVo>();
        List<ProcessInsVo> list = new ArrayList<>();
        /*ProcessInstanceQuery query = runtimeService.createProcessInstanceQuery()
                .orderByProcessInstanceId().desc();
        if(StrUtil.isNotBlank(categoryId)){
            query.processDefinitionCategory(categoryId);
        }
        if(StrUtil.isNotBlank(key)) {
            query.processDefinitionKey(key);
        }
        List<ProcessInstance> taskLists =  query.list();
        */
        YongLaiChuanCan chuanCan = new YongLaiChuanCan();
        if(StrUtil.isNotBlank(name)){
            chuanCan.setName(name);
        }
        if(StrUtil.isNotBlank(depId)){
            chuanCan.setDepId(depId);
        }
        if(StrUtil.isNotBlank(categoryId)){
            chuanCan.setCategoryId(categoryId);
        }
        if(StrUtil.isNotBlank(key)){
            chuanCan.setKey(key);
        }
        if(StrUtil.isNotBlank(locality)){
            chuanCan.setLocality(locality);
        }
        if(StrUtil.isNotBlank(eventDescribe)){
            chuanCan.setEventDescribe(eventDescribe);
        }
        if(StrUtil.isNotBlank(eventType)){
            chuanCan.setEventType(eventType);
        }
        if(StrUtil.isNotBlank(eventNum)){
            chuanCan.setEventNum(eventNum);
        }
        if(StrUtil.isNotBlank(stage)){
            chuanCan.setStage(stage);
        }


        List<ProcessInstance> taskInstances1 =  new LinkedList<>();
        String departmentId = securityUtil.getCurrUser().getDepartmentId();
        String title = departmentService.get(departmentId).getTitle();
        List<ActProcessInstance> byTime = processInstanceService.findByNameDepIdKeyTime(chuanCan,searchVo);
        if("北京市顺义区".equals(title)){
            for (int i=0;i<byTime.size();i++){
                taskInstances1.add(byTime.get(i));
            }
        }else {
            for (int i=0;i<byTime.size();i++){
                try {
                    if(byTime.get(i).getParentId().equals(departmentId)){
                        taskInstances1.add(byTime.get(i));
                    }
                    if (departmentId.equals(byTime.get(i).getDepartmentId())) {
                        taskInstances1.add(byTime.get(i));
                    }
                }catch (Exception e){
                    taskInstances1.add(byTime.get(i));
                }
            }
        }
        List<ProcessInstance> depPineIdArr =  new LinkedList<>();
        if(StrUtil.isNotBlank(depPineId)){
            for (int i=0;i<taskInstances1.size();i++){
                //获取此事件所有节点
                List<HistoricTaskInstance> taskList = historyService.createHistoricTaskInstanceQuery()
                        .processInstanceId(taskInstances1.get(i).getProcessInstanceId()).orderByHistoricTaskInstanceEndTime().asc().list();
                List<String> departmentIds = new LinkedList<>();
                for (HistoricTaskInstance task : taskList){
                    List<HistoricIdentityLink> identityLinks = historyService.getHistoricIdentityLinksForTask(task.getId());
                    for(HistoricIdentityLink hik : identityLinks){
                        // 关联候选用户（分配的候选用户审批人）
                        if("candidate".equals(hik.getType())&&StrUtil.isNotBlank(hik.getUserId())){
                            //获取下派用户的部门
                            String departmentId2 = "";
                            try {
                                departmentId2 = userService.get(hik.getUserId()).getDepartmentId();
                                departmentIds.add(departmentId2);
                            }catch (Exception e1){}
                        }
                    }
                }
                for (int j=0;j<departmentIds.size();j++){
                    if (depPineId.equals(departmentIds.get(j))){
                        depPineIdArr.add(taskInstances1.get(i));
                        break;
                    }
                }
            }
        }else {
            depPineIdArr = taskInstances1;
        }
        page.setTotalElements((long) depPineIdArr.size());
        int first =  (pageVo.getPageNumber()-1) * pageVo.getPageSize();
        int end = depPineIdArr.size();
        if((first+pageVo.getPageSize())<end){
            end = first+pageVo.getPageSize();
        }
        List<ProcessInstance> processInstanceList = depPineIdArr.subList(first,end);

       /* page.setTotalElements(query.count());
        int first =  (pageVo.getPageNumber()-1) * pageVo.getPageSize();
        List<ProcessInstance> processInstanceList = query.listPage(first, pageVo.getPageSize());*/
        processInstanceList.forEach(e -> {
            list.add(new ProcessInsVo(e));
        });
        list.forEach(e -> {
            List<HistoricIdentityLink> identityLinks = historyService.getHistoricIdentityLinksForProcessInstance(e.getId());
            for(HistoricIdentityLink hik : identityLinks){
                // 关联发起人
                if("starter".equals(hik.getType())&&StrUtil.isNotBlank(hik.getUserId())){
                    try {
                        e.setApplyer(userService.get(hik.getUserId()).getUsername());
                    }catch (Exception e1){
                        e.setApplyer("此用户已注销");
                    }
                }
            }
            // 关联当前任务
            Task task = taskService.createTaskQuery().processInstanceId(e.getId()).singleResult();
            if(task!=null){
                e.setCurrTaskName(task.getName());
            }
            // 关联流程表单路由
            ActProcess actProcess = actProcessService.get(e.getProcDefId());
            if(actProcess!=null){
                e.setRouteName(actProcess.getRouteName());
            }
            // 关联业务表id
            ActBusiness actBusiness = actBusinessService.get(e.getBusinessKey());
            if(actBusiness!=null){
                e.setTableId(actBusiness.getTableId());
                EventReport eventReport = eventReportService.get(actBusiness.getTableId());
                if(eventReport!=null){
                    e.setEventType(eventReport.getEventType());
                    e.setEventDescribe(eventReport.getEventDescribe());
                    e.setLocality(eventReport.getLocality());
                    e.setEventNum(eventReport.getEventNum());
                    e.setFront(eventReport.getFront());
                    e.setTaskEndTime(eventReport.getTaskEndTime());
                }
            }
        });
        page.setContent(list);
        return new ResultUtil<Object>().setData(page);
    }

    @RequestMapping(value = "/getFinishedProcess", method = RequestMethod.GET)
    @ApiOperation(value = "获取结束的的流程实例")
    public Result<Object> getFinishedProcess(@RequestParam(required = false) String name,
                                             @RequestParam(required = false) String depId,
                                             @RequestParam(required = false) String categoryId,
                                             @RequestParam(required = false) String key,
                                             @RequestParam(required = false) String locality,
                                             @RequestParam(required = false) String eventDescribe,
                                             @RequestParam(required = false) String eventType,
                                             @RequestParam(required = false) String eventNum,
                                             @RequestParam(required = false) String depPineId,
                                             @ModelAttribute SearchVo searchVo,
                                             @ModelAttribute PageVo pageVo){
        ActPage<HistoricProcessInsVo> page = new ActPage<HistoricProcessInsVo>();
        List<HistoricProcessInsVo> list = new ArrayList<>();

        /*HistoricProcessInstanceQuery query = historyService.createHistoricProcessInstanceQuery().finished().
                orderByProcessInstanceEndTime().desc();

        if(StrUtil.isNotBlank(name)){
            query.processInstanceNameLike("%"+name+"%");
        }
        if(StrUtil.isNotBlank(categoryId)){
            query.processDefinitionCategory(categoryId);
        }
        if(StrUtil.isNotBlank(key)) {
            query.processDefinitionKey(key);
        }
        if(StrUtil.isNotBlank(searchVo.getStartDate())&&StrUtil.isNotBlank(searchVo.getEndDate())){
            Date start = DateUtil.parse(searchVo.getStartDate());
            Date end = DateUtil.parse(searchVo.getEndDate());
            query.finishedAfter(start);
            query.finishedBefore(DateUtil.endOfDay(end));
        }

        List<HistoricProcessInstance> taskLists =  query.list();
        List<HistoricProcessInstance> taskInstances =  new ArrayList<>();

        //根据部门查找
        if(null == depId || "".equals(depId)){
            depId = securityUtil.getCurrUser().getDepartmentId();
            String title = departmentService.get(depId).getTitle();
            if(!"北京市顺义区".equals(title)){
                for(int i = 0;i<taskLists.size();i++){
                    HistoricProcessInsVo htv = new HistoricProcessInsVo(taskLists.get(i));
                    List<HistoricIdentityLink> identityLinks = historyService.getHistoricIdentityLinksForProcessInstance(htv.getId());
                    for(HistoricIdentityLink hik : identityLinks){
                        // 关联发起人
                        if("starter".equals(hik.getType())&&StrUtil.isNotBlank(hik.getUserId())){
                            List<Department> parentId = departmentService.findParentId(depId);
                            for (int j=0;j<parentId.size();j++){
                                if (parentId.get(j).getId().equals(userService.get(hik.getUserId()).getDepartmentId())) {
                                    taskInstances.add(taskLists.get(i));
                                }
                            }
                            if(depId.equals(userService.get(hik.getUserId()).getDepartmentId())){
                                taskInstances.add(taskLists.get(i));
                            }
                        }
                    }
                }
            }else{
                taskInstances = taskLists;
            }
        }else if(StrUtil.isNotBlank(depId)){
            for(int i = 0;i<taskLists.size();i++){
                HistoricProcessInsVo htv = new HistoricProcessInsVo(taskLists.get(i));
                List<HistoricIdentityLink> identityLinks = historyService.getHistoricIdentityLinksForProcessInstance(htv.getId());
                for(HistoricIdentityLink hik : identityLinks){
                    // 关联发起人
                    if("starter".equals(hik.getType())&&StrUtil.isNotBlank(hik.getUserId())){
                        if(depId.equals(userService.get(hik.getUserId()).getDepartmentId())){
                            taskInstances.add(taskLists.get(i));
                        }
                    }
                }
            }
        }else{
            taskInstances = taskLists;
        }
        page.setTotalElements((long) taskInstances.size());
        int first =  (pageVo.getPageNumber()-1) * pageVo.getPageSize();
        int end = taskInstances.size();
        if((first+pageVo.getPageSize())<end){
            end = first+pageVo.getPageSize();
        }
        List<HistoricProcessInstance> processInstanceList = taskInstances.subList(first,end);
*/
        YongLaiChuanCan chuanCan = new YongLaiChuanCan();
        if(StrUtil.isNotBlank(name)){
            chuanCan.setName(name);
        }
        if(StrUtil.isNotBlank(depId)){
            chuanCan.setDepId(depId);
        }
        if(StrUtil.isNotBlank(categoryId)){
            chuanCan.setCategoryId(categoryId);
        }
        if(StrUtil.isNotBlank(key)){
            chuanCan.setKey(key);
        }
        if(StrUtil.isNotBlank(locality)){
            chuanCan.setLocality(locality);
        }
        if(StrUtil.isNotBlank(eventDescribe)){
            chuanCan.setEventDescribe(eventDescribe);
        }
        if(StrUtil.isNotBlank(eventType)){
            chuanCan.setEventType(eventType);
        }
        if(StrUtil.isNotBlank(eventNum)){
            chuanCan.setEventNum(eventNum);
        }
        List<ActHistoricProcessInstance> historicByDepIdKeyTime = processInstanceService.findHistoricByDepIdKeyTime(chuanCan, searchVo);
        List<HistoricProcessInstance> taskInstances =  new ArrayList<>();
        for (ActHistoricProcessInstance ha:historicByDepIdKeyTime ){
            taskInstances.add(ha);
        }

        List<HistoricProcessInstance> depPineIdArr =  new LinkedList<>();
        if(StrUtil.isNotBlank(depPineId)){
            for (int i=0;i<taskInstances.size();i++){
                //获取此事件所有节点
                List<HistoricTaskInstance> taskList = historyService.createHistoricTaskInstanceQuery()
                        .processInstanceId(taskInstances.get(i).getId()).orderByHistoricTaskInstanceEndTime().asc().list();
                List<String> departmentIds = new LinkedList<>();
                for (HistoricTaskInstance task : taskList){
                    List<HistoricIdentityLink> identityLinks = historyService.getHistoricIdentityLinksForTask(task.getId());
                    for(HistoricIdentityLink hik : identityLinks){
                        // 关联候选用户（分配的候选用户审批人）
                        if("candidate".equals(hik.getType())&&StrUtil.isNotBlank(hik.getUserId())){
                            //获取下派用户的部门
                            String departmentId2 = "";
                            try {
                                departmentId2 = userService.get(hik.getUserId()).getDepartmentId();
                                departmentIds.add(departmentId2);
                            }catch (Exception e1){}
                        }
                    }
                }
                for (int j=0;j<departmentIds.size();j++){
                    if (depPineId.equals(departmentIds.get(j))){
                        depPineIdArr.add(taskInstances.get(i));
                        break;
                    }
                }
            }
        }else {
            depPineIdArr = taskInstances;
        }

        page.setTotalElements((long) depPineIdArr.size());
        int first =  (pageVo.getPageNumber()-1) * pageVo.getPageSize();
        int end = depPineIdArr.size();
        if((first+pageVo.getPageSize())<end){
            end = first+pageVo.getPageSize();
        }
        List<HistoricProcessInstance> processInstanceList = depPineIdArr.subList(first,end);
        processInstanceList.forEach(e -> {
            list.add(new HistoricProcessInsVo(e));
        });
        list.forEach(e -> {
            List<HistoricIdentityLink> identityLinks = historyService.getHistoricIdentityLinksForProcessInstance(e.getId());
            for(HistoricIdentityLink hik : identityLinks){
                // 关联发起人
                if("starter".equals(hik.getType())&&StrUtil.isNotBlank(hik.getUserId())){
                    try {
                        e.setApplyer(userService.get(hik.getUserId()).getUsername());
                    }catch (Exception e1){
                        e.setApplyer("此用户已注销");
                    }
                }
            }
            // 关联流程表单路由
            ActProcess actProcess = actProcessService.get(e.getProcDefId());
            if(actProcess!=null){
                e.setRouteName(actProcess.getRouteName());
            }
            // 关联业务表id和结果
            ActBusiness actBusiness = actBusinessService.get(e.getBusinessKey());
            if(actBusiness!=null){
                e.setTableId(actBusiness.getTableId());
                String reason = e.getDeleteReason();
                if(reason==null){
                    e.setResult(ActivitiConstant.RESULT_PASS);
                }else if(reason.contains(ActivitiConstant.CANCEL_PRE)){
                    e.setResult(ActivitiConstant.RESULT_CANCEL);
                    if(reason.length()>9){
                        e.setDeleteReason(reason.substring(9));
                    }else{
                        e.setDeleteReason("");
                    }
                }else if(ActivitiConstant.BACKED_FLAG.equals(reason)){
                    e.setResult(ActivitiConstant.RESULT_FAIL);
                    e.setDeleteReason("");
                }else if(reason.contains(ActivitiConstant.DELETE_PRE)){
                    e.setResult(ActivitiConstant.RESULT_DELETED);
                    if(reason.length()>8){
                        e.setDeleteReason(reason.substring(8));
                    }else{
                        e.setDeleteReason("");
                    }
                }else{
                    e.setResult(ActivitiConstant.RESULT_PASS);
                }
                if(actBusiness!=null){
                    e.setTableId(actBusiness.getTableId());
                    EventReport eventReport = eventReportService.get(actBusiness.getTableId());
                    if(eventReport!=null){
                        e.setEventType(eventReport.getEventType());
                        e.setEventDescribe(eventReport.getEventDescribe());
                        e.setLocality(eventReport.getLocality());
                        e.setEventNum(eventReport.getEventNum());
                        e.setFront(eventReport.getFront());
                        e.setLater(eventReport.getLater());
                    }
                }
            }
        });
        page.setContent(list);
        return new ResultUtil<Object>().setData(page);
    }

    @RequestMapping(value = "/getFirstNode/{procDefId}", method = RequestMethod.GET)
    @ApiOperation(value = "通过流程定义id获取第一个任务节点")
    public Result<ProcessNodeVo> getFirstNode(@ApiParam("流程定义id") @PathVariable String procDefId){

        ProcessNodeVo node = actProcessService.getFirstNode(procDefId);
        return new ResultUtil<ProcessNodeVo>().setData(node);
    }

    @RequestMapping(value = "/getUsers", method = RequestMethod.GET)
    @ApiOperation(value = "重新申请查找审批人")
    public Result<ProcessNodeVo> getUsers(@RequestParam(required = false) String tableId,
                                          @RequestParam(required = false) String procDefId){

        EventReport eventReport = eventReportService.get(tableId);
        String userId = securityUtil.getCurrUser().getId();
        ProcessNodeVo node = actProcessService.getFirstNode(procDefId);
        List<User> listUser = eventReportService.findUsers(eventReport,userId,procDefId);
        node.setUsers(listUser);
        return new ResultUtil<ProcessNodeVo>().setData(node);
    }

    @RequestMapping(value = "/getNextNode/{procInstId}/{type}", method = RequestMethod.GET)
    @ApiOperation(value = "通过流程实例获取下一个节点")
    public Result<ProcessNodeVo> getNextNode(@ApiParam("流程实例id") @PathVariable String procInstId,@PathVariable String type){

        ProcessNodeVo node = actProcessService.getNextNode(procInstId,type);
        return new ResultUtil<ProcessNodeVo>().setData(node);
    }

    @RequestMapping(value = "/getNode/{nodeId}", method = RequestMethod.GET)
    @ApiOperation(value = "通过节点nodeId获取审批人")
    public Result<ProcessNodeVo> getNode(@ApiParam("节点nodeId") @PathVariable String nodeId){

        ProcessNodeVo node = actProcessService.getNode(nodeId);
        return new ResultUtil<ProcessNodeVo>().setData(node);
    }

    @RequestMapping(value = "/getNodePeople/{nodeId}/{id}", method = RequestMethod.GET)
    @ApiOperation(value = "通过节点nodeId获取审批人")
    public Result<ProcessNodeVo> getNodePeople(@ApiParam("节点nodeId") @PathVariable String nodeId,@ApiParam("流程实例id") @PathVariable String id){

        List<User> list = new ArrayList<>();

        List<HistoricTaskInstance> taskList = historyService.createHistoricTaskInstanceQuery()
                .processInstanceId(id).orderByHistoricTaskInstanceEndTime().asc().list();

        // 转换vo
        taskList.forEach(e -> {
            if(e.getTaskDefinitionKey() != null && e.getTaskDefinitionKey().equals(nodeId)){
                List<HistoricIdentityLink> identityLinks = historyService.getHistoricIdentityLinksForTask(e.getId());
                for(HistoricIdentityLink hik : identityLinks){
                    if("candidate".equals(hik.getType())&&StrUtil.isNotBlank(hik.getUserId())){
                        User user = userService.get(hik.getUserId());
                        if(user!=null){
                            list.add(user);
                        }
                    }
                }
            }
        });

        ProcessNodeVo node = new ProcessNodeVo();
        node.setUsers(actProcessService.removeDuplicate(list));
        return new ResultUtil<ProcessNodeVo>().setData(node);
    }

    @RequestMapping(value = "/getHighlightImg/{id}", method = RequestMethod.GET)
    @ApiOperation(value = "获取高亮实时流程图")
    public void getHighlightImg(@ApiParam("流程实例id") @PathVariable String id,
                                HttpServletResponse response){

        InputStream inputStream = null;
        ProcessInstance pi = null;
        String picName = "";
        // 查询历史
        HistoricProcessInstance hpi = historyService.createHistoricProcessInstanceQuery().processInstanceId(id).singleResult();
        if (hpi.getEndTime() != null) {
            // 已经结束流程获取原图
            ProcessDefinition pd = repositoryService.createProcessDefinitionQuery().processDefinitionId(hpi.getProcessDefinitionId()).singleResult();
            picName = pd.getDiagramResourceName();
            inputStream = repositoryService.getResourceAsStream(pd.getDeploymentId(), pd.getDiagramResourceName());
        } else {
            pi = runtimeService.createProcessInstanceQuery().processInstanceId(id).singleResult();
            BpmnModel bpmnModel = repositoryService.getBpmnModel(pi.getProcessDefinitionId());


            List<String> highLightedActivities = new ArrayList<String>();
            // 高亮任务节点
            List<Task> tasks = taskService.createTaskQuery().processInstanceId(id).list();
            for (Task task : tasks) {
                highLightedActivities.add(task.getTaskDefinitionKey());
            }

            List<String> highLightedFlows = new ArrayList<String>();
            ProcessDiagramGenerator diagramGenerator = processEngineConfiguration.getProcessDiagramGenerator();
            inputStream = diagramGenerator.generateDiagram(bpmnModel, "png", highLightedActivities, highLightedFlows,
                    properties.getActivityFontName(), properties.getLabelFontName(), properties.getLabelFontName(),null, 1.0);
            picName = pi.getName()+".png";
        }
        try {
            response.setContentType("application/octet-stream;charset=UTF-8");
            response.setHeader("Content-Disposition", "attachment; filename=" + URLEncoder.encode(picName, "UTF-8"));
            byte[] b = new byte[1024];
            int len = -1;
            while ((len = inputStream.read(b, 0, 1024)) != -1) {
                response.getOutputStream().write(b, 0, len);
            }
            response.flushBuffer();
        } catch (IOException e) {
            log.error(e.toString());
            throw new XbootException("读取流程图片失败");
        }
    }

    @RequestMapping(value = "/updateInsStatus", method = RequestMethod.POST)
    @ApiOperation(value = "激活或挂起流程实例")
    public Result<Object> updateStatus(@ApiParam("流程实例id") @RequestParam String id,
                                       @RequestParam Integer status){

        if(ActivitiConstant.PROCESS_STATUS_ACTIVE.equals(status)){
            runtimeService.activateProcessInstanceById(id);
        }else if(ActivitiConstant.PROCESS_STATUS_SUSPEND.equals(status)){
            runtimeService.suspendProcessInstanceById(id);
        }

        return new ResultUtil<Object>().setData("修改成功");
    }

    @RequestMapping(value = "/delInsByIds/{ids}", method = RequestMethod.DELETE)
    @ApiOperation(value = "通过id删除运行中的实例")
    public Result<Object> delInsByIds(@PathVariable String[] ids,
                                      @RequestParam(required = false) String reason){

        if(StrUtil.isBlank(reason)){
            reason = "";
        }
        for(String id : ids){
            // 关联业务状态结束
            ProcessInstance pi = runtimeService.createProcessInstanceQuery().processInstanceId(id).singleResult();
            ActBusiness actBusiness = actBusinessService.get(pi.getBusinessKey());
            actBusiness.setStatus(ActivitiConstant.STATUS_TO_APPLY);
            actBusiness.setResult(ActivitiConstant.RESULT_TO_SUBMIT);
            actBusinessService.update(actBusiness);
            runtimeService.deleteProcessInstance(id, ActivitiConstant.DELETE_PRE+reason);
        }
        return new ResultUtil<Object>().setData("删除成功");
    }

    @RequestMapping(value = "/delHistoricInsByIds/{ids}", method = RequestMethod.DELETE)
    @ApiOperation(value = "通过id删除已结束的实例")
    public Result<Object> delHistoricInsByIds(@PathVariable String[] ids){

        for(String id : ids){
            historyService.deleteHistoricProcessInstance(id);
        }
        return new ResultUtil<Object>().setData("删除成功");
    }

    /**
     * 通过部门id获取审批人
     * @param id
     * @return
     */
    @RequestMapping(value = "/getDepaByUser/{id}", method = RequestMethod.GET)
    @ApiOperation(value = "通过部门id获取审批人")
    public Result<ProcessNodeVo> getDepaByUser(@ApiParam("部门id") @PathVariable String id){
        List<User> byDepartmentId = userService.findByDepartmentId(id);
        ProcessNodeVo node = new ProcessNodeVo();
        node.setUsers(byDepartmentId);
        System.out.println(node.getId());
        return new ResultUtil<ProcessNodeVo>().setData(node);
    }
}
